﻿using IFix.Editor;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Reflection;

public class InjectFixEditor : EditorWindow
{
    private TCPListener server;

    [MenuItem("InjectFix/Window编辑器")]
    public static void OpenInjectFixEditor()
    {
        Rect wr = new Rect(0, 0, 250, 500);
        InjectFixEditor window = EditorWindow.GetWindowWithRect<InjectFixEditor>(wr, true, "InjectFix", true);
        window.Show();
       
    }
    private void OnDestroy()
    {
        Close();
    }

    public InjectFixEditor()
    {
        server = new TCPListener();
        server.StartServer();
    }
    public static string[] GetBuildScenes()
    {
        List<string> names = new List<string>();
        foreach (EditorBuildSettingsScene e in EditorBuildSettings.scenes)
        {
            if (e == null)
                continue;
            if (e.enabled)
                names.Add(e.path);
        }
        return names.ToArray();
    }
    private Rect textAreaRect = new Rect(0, 0, 250, 200);
    private Vector2 textScrollPos = Vector2.zero;
    private string TextAreaContext = string.Empty;
    private string bytesPath = @"C:\WORK\InjectFix\Source\UnityProj";
    void OnGUI()
    {
        GUILayout.BeginVertical();
        if (GUILayout.Button("Inject"))
        {
            IFixEditor.InjectAssemblys();
        }
        GUILayout.Space(5);
        if (GUILayout.Button("ReloadShaderC"))
        {
            CompileAllShader(false);
            IFixEditor.InjectAssemblys();
            BuildPipeline.BuildPlayer(GetBuildScenes(), Application.dataPath, BuildTarget.Android, BuildOptions.Development);
        }
        GUILayout.Space(5);
        if (GUILayout.Button("Patch"))
        {
            IFixEditor.Patch();
        }
        GUILayout.Space(5);
        if (GUILayout.Button("CleanAssembly"))
        {
            IFixEditor.CleanAssembly();
        }
        GUILayout.Space(5);
        if (GUILayout.Button("选择bytes文件夹"))
        {
            bytesPath = EditorUtility.OpenFolderPanel("选择PatchBytes文件夹", Application.dataPath, string.Empty);
        }
        GUILayout.Label(bytesPath); 
        if (GUILayout.Button("读取patch数据并推送到到客户端"))
        {
            var files = Directory.GetFiles(bytesPath);
            string csharpDll = string.Empty;
            string csharpFisrtDll = string.Empty;
            foreach (var file in files)
            {
                if (file.EndsWith("Assembly-CSharp-firstpass.patch.bytes"))
                {
                    csharpFisrtDll = file;
                }
                else if (file.EndsWith("Assembly-CSharp.patch.bytes"))
                {
                    csharpDll = file;
                }
            }

            SendMsg(csharpDll, DllType.CSharpDll);
            SendMsg(csharpFisrtDll, DllType.FirstDll);
        }
       
        GUILayout.BeginScrollView(textScrollPos);
        TextAreaContext = GUILayout.TextField(TextAreaContext);
        GUILayout.EndScrollView();

        GUILayout.EndVertical();
    }

    private void SendMsg(string filepath, DllType type)
    {
        var fst = File.OpenRead(filepath);
        var fileSize = fst.Length;
        byte[] array = new byte[fileSize];
        fst.Read(array, 0, array.Length);
        fst.Close();

        List<byte> netData = new List<byte>();
        netData.AddRange(bytestools.int2byte((int)type));
        netData.AddRange(bytestools.int2byte(array.Length));
        netData.AddRange(array);


        string log = string.Format("<color=red> 向客户端推送的文件:{0}, size:{1},allSize:{2} </color>",filepath,fileSize,netData.Count);
        Debug.Log(log);
        server.SendMsg(netData.ToArray());

    }

    public static void CompileAllShader(bool deleteAllCache = false)
    {
        bool done = false;
        foreach (Assembly assembly in System.AppDomain.CurrentDomain.GetAssemblies())
        {
            if (assembly.FullName.StartsWith("UnityEditor,", System.StringComparison.Ordinal))
            {
                foreach (System.Type t in assembly.GetTypes())
                {
                    if (t.FullName.Equals("UnityEditor.ShaderUtil"))
                    {
                        MethodInfo mi = t.GetMethod("ReloadAllShaders", BindingFlags.NonPublic | BindingFlags.Static);
                        if (mi != null)
                        {
                            if (deleteAllCache)
                            {
                                Debug.Log("删除编译缓存....");

                                string shaderCachePath = System.IO.Path.Combine(Application.dataPath, "../Library/ShaderCache");
                                string shaerCacaheDBPath = System.IO.Path.Combine(Application.dataPath, "../Library/ShaderCache.db");
                                if (System.IO.Directory.Exists(shaderCachePath))
                                {
                                    System.IO.Directory.Delete(shaderCachePath, true);
                                }
                                if (System.IO.Directory.Exists(shaerCacaheDBPath))
                                {
                                    System.IO.Directory.Delete(shaerCacaheDBPath, true);
                                }
                            }

                            Debug.Log("Relaod Shader....");

                            mi.Invoke(null, null);
                            done = true;
                            break;
                        }
                    }
                }
            }
            if (done)
            {
                break;
            }
        }


        Debug.Log("ALL Done!");

    }
}
